﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Diagnostics;
using System.Windows.Threading;

using System.Collections;


using System.DirectoryServices.AccountManagement;

namespace mns
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    /// 
    public partial class App : Application
    {

        //
        public delegate void Msghandler();

        //it is the work thread's handle;
        Thread workthread;

        private int ReceiveId;
        private int SendId;

        //
        void NotifyMenu( List<int> tasksid)
        {

            //Create a Maindow for password
            MainWindow ptr = new MainWindow(tasksid);
            ptr.ShowDialog();

            

        }

        //an idle Task in UI thread
        void IdleRun()
        {
            // add self into the queue of current dispatcher            
            object o;
            if (MSGL.GetMessage(ReceiveId, out o, 0))
            {
                UIMM work_uimm = (UIMM)o;
         
                switch(work_uimm.cmd)
                {
                    case UIMM.UIMM_MSG.NOTIFY:
                        NotifyMenu(((IEnumerable)work_uimm.data).Cast<int>().ToList());
                        work_uimm.cmd = UIMM.UIMM_MSG.RESPONSE;
                        MSGL.SendMessage(SendId,work_uimm);
                        break;
                }
            }
            Dispatcher.BeginInvoke(DispatcherPriority.SystemIdle, new Msghandler(IdleRun));  
        }


        

        // check if the work thread is exited or not in order to decide whether thread  need to be stop or not after exiting application
        bool WorkThreadExited = false;
        public bool CheckIfWorkThreadExited()
        {
            return WorkThreadExited;
        }
        public void SetWorkThreadExit()
        {
            WorkThreadExited = true;
        }



        // check if there is a instance of process existed 
        public bool CheckIsOnlyOneInstanceRunning()
        {
            Process current = Process.GetCurrentProcess();
            Process[] processed = Process.GetProcessesByName(current.ProcessName);

            if(processed.Count()>1)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
       

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            

            // check if there is another instance running
            if (CheckIsOnlyOneInstanceRunning())
            {
                MessageBox.Show("there is already an instance running in the system!");
                this.Shutdown();
                return;
            }

            //
            ReceiveId = MSGL.CreateMsg();
            SendId = MSGL.CreateMsg();
             
            // build  a worker thread here to monitor each tasks every period 
            Monitor.ReceiveId = SendId;
            Monitor.SendId = ReceiveId;

            workthread = new Thread(new ThreadStart(Monitor.Run));
            workthread.Start();
            SetWorkThreadExit();
            IdleRun();

            
        }


        private void Application_Exit(object sender, ExitEventArgs e)
        {
            
            if (CheckIfWorkThreadExited())
            {
                workthread.Abort();
                workthread.Join();  
            }
                 
        }



    }

}
